using System;
using System.Text.RegularExpressions;
using System.Collections;
using System.Data;
using Dimok.Data.Database ;

namespace Dimok{
	/// <summary>
	/// Summary description for XmlEx.
	/// </summary>
	public class XmlEx{
		public XmlEx(){}
		#region GetLevels ============
		public static string CleanLevelsXML(string xml,string tagName){
			Regex re = new Regex("(</?"+tagName+")_\\d+");
			return re.Replace(xml,"$1");
		}
		public static string GetLevelsXml(string connStr,string sql,string parentField,string childField,string prefix,string levelName){
			return GetLevelsXml(connStr,sql,parentField,childField,prefix,levelName,"");
		}
		public static string GetLevelsXml(string connStr,string sql,string parentField,string childField,string prefix,string levelName,string orderBy){
			DataSet ds = GetLevels(connStr,sql,parentField,childField,prefix,levelName,orderBy);
			Regex re = new Regex("(</?"+levelName+")_\\d+");
			string ret = re.Replace(ds.GetXml(),"$1");
			//throw new Exception("\n"+ret+"\n");
			return prefix != "" ? ret.Replace(levelName,prefix+":"+levelName) : ret;
		}
		//TODO:Improve speed by using view instead of pulling two queries
		public static DataSet GetLevels(string connStr,string sql,string parentField,string childField,string prefix,string levelName){
			return GetLevels(connStr,sql,parentField,childField,prefix,levelName,"");
		}
		private static DataTable MakeRootsTable(DataTable dtAll,string ParentIDFieldName,string levelName){
			return MakeLevelTable(dtAll,ParentIDFieldName,levelName,0);
		}
		private static DataTable MakeLevelTable(DataTable dtData,string ParentIDFieldName,string levelName,int parentID){
			DataTable dtLevel = dtData.Clone();
			dtLevel.TableName = levelName;
			DataView dv = dtData.DefaultView;
			dv.RowFilter = ParentIDFieldName + "="+parentID;
			foreach( DataRowView drv in dv )
				dtLevel.Rows.Add(drv.Row.ItemArray);
			return dtLevel;
		}
		public static DataSet GetLevels(string connStr,string sql,string parentField,string childField,string prefix,string levelName,string orderBy){
			DataSet dsTop = SQLHelperEx.ExecuteDatasetEx(connStr,sql+" "+orderBy);
			if( dsTop.Tables[0].Rows.Count == 0 )return dsTop;
			DataTable dtRoots = MakeRootsTable(dsTop.Tables[0],childField,levelName);
			dsTop.Tables.Add(dtRoots);
			DataTable dtTempl = dsTop.Tables[0];
			dsTop.Tables.Remove(dtTempl);
			GetSubLevel(dtRoots,dtTempl,parentField,childField,prefix,levelName);
			SQLHelperEx.SetColumnsMapping(dsTop,MappingType.Attribute);
			return dsTop;
		}
		private static void GetSubLevel(DataTable dtParent,DataTable dtChild,string parentField,string childField,string prefix,string levelName){
			GetSubLevel(dtParent,dtChild,parentField,childField,prefix,levelName,0);
		}
		private static void GetSubLevel(DataTable dtParent,DataTable dtChild,string parentField,string childField,string prefix,string levelName,int level){
			DataTable dt = MakeLevelTable(dtParent,dtChild,childField);
			if( dt.Rows.Count == 0 )return;
			int parentID = (int)dtParent.Rows[0][childField];
			dt.TableName = levelName+"_"+level;
			if( prefix.Length > 0 )dt.Prefix = prefix;
			dtParent.DataSet.Tables.Add(dt);
			DataRelation dr = new DataRelation("REL_"+level,dtParent.Columns[parentField],dt.Columns[childField],true);
			dr.Nested = true;
			dtParent.DataSet.Relations.Add(dr);
			GetSubLevel(dt,dtChild,parentField,childField,prefix,levelName,level+1);
		}
		private static void GetSubLevel_(DataTable dtParent,DataTable dtChild,string parentField,string childField,string prefix,string levelName,int level){
			string inFilter = GetINFilter(dtParent.Rows,parentField);
			if( inFilter == "" )return;
			DataTable dt = GetChildTable(inFilter,dtChild,childField);
			if( dt.Rows.Count == 0 )return;
			int parentID = (int)dtParent.Rows[0][childField];
			dt.TableName = levelName+"_"+level;
			if( prefix.Length > 0 )dt.Prefix = prefix;
			dtParent.DataSet.Tables.Add(dt);
			DataRelation dr = new DataRelation("REL_"+level,dtParent.Columns[parentField],dt.Columns[childField],true);
			dr.Nested = true;
			dtParent.DataSet.Relations.Add(dr);
			GetSubLevel(dt,dtChild,parentField,childField,prefix,levelName,level+1);
		}
		private static DataTable GetChildTable(string inFilter,DataTable dt,string filterField){
			DataRow[] rows = dt.Select(filterField+" IN("+inFilter+")");
			DataTable dtOut = dt.Clone();
			foreach( DataRow row in rows){
				dtOut.Rows.Add(row.ItemArray);
			}
			SQLHelperEx.SetColumnsMapping(dtOut,MappingType.Attribute);
			//dtOut.Columns["Lable"].ColumnMapping = MappingType.SimpleContent;
			return dtOut;
		}
		private static string GetINFilter(DataRowCollection rows,string inField){
			ArrayList al = new ArrayList();
			foreach( DataRow row in rows )
				al.Add(row[inField].ToString());
			return al.Count > 0 ? string.Join(",",(string[])al.ToArray(typeof(System.String))) : "";
		}
		#endregion Levels ============

	}
}
